home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
shadowlib.lha
/
shadow
/
Examples
/
Source
/
gui.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-13
|
59KB
|
1,866 lines
/*
* First run attempt at a functional GUI library.
* I agree, it sucks, but it's good enough, as Americans USED to
* say.
*
* COPYRIGHT: 1991, 1992 David C. Navas
* License granted to SwRI to modify and use as per site
* license. Further distribution license rights granted
* upon receipt of agreed upon compensation.
* All Other Rights Reserved by Author
*/
#include "gui.h"
/*
* Of course! max() is in string.h....
*/
#define USE_BUILTIN_MATH
#include <string.h>
#include <libraries/diskfont.h>
#include <libraries/asl.h>
#include <clib/diskfont_protos.h>
#include <clib/graphics_protos.h>
#include <clib/asl_protos.h>
#include <clib/utility_protos.h>
#include <pragmas/diskfont_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/asl_pragmas.h>
#include <pragmas/utility_pragmas.h>
#include <shadow/coreRoot.h>
#include <shadow/coreMeta.h>
#include <shadow/misc.h>
#include <shadow/process.h>
#include <shadow/semaphore.h>
#include <shadow/shadowBase.h>
#include <shadow/shadow_proto.h>
#include <shadow/shadow_pragmas.h>
#include <dos/dostags.h>
#include <ipc.h>
#include <ipc_proto.h>
extern struct Library * __far SysBase;
extern struct Library * __far DOSBase;
struct Library * __far GadToolsBase;
struct Library * __far IntuitionBase;
extern struct Library * __far DiskfontBase;
extern struct Library * __far GfxBase;
extern struct Library * __far ShadowBase;
extern struct Library * __far UtilityBase;
struct Library * __far AslBase;
/*
* external class definitions.
*/
extern char GuiProcClassName[],
AslProcClassName[],
GuiTaskName[],
GuiClassName[],
WindowClassName[],
GadgTClassName[],
AslClassName[];
void RemoveWinSafely(struct Window *win);
void StripIntuiMessages(struct MsgPort *port, struct Window *win);
struct TextAttr __far ta = {"topaz.font", 11, FS_NORMAL,
FPF_ROMFONT | FPF_DISKFONT};
struct TextFont * __far tf;
OBJECT __GlobalFocus = NULL; /* one valid focus only */
/*
* ==========================================================================
* = =
* = Class definition for the GUI process. =
* = =
* ==========================================================================
*/
ATTRIBUTE_TAG guiProcAttrs[] =
{
ATTR_GUIPROCESS, sizeof(struct GuiProcess), NULL,
TAG_END
};
ARGUMENT_TAG REF_AssociateGuiProcObject[] =
{
{
'JSTR', 4, 0
},
{
TAG_END, SHADOW_RETURN_OBJECT, 0
}
};
void __saveds *AssociateGuiProcObject(METHOD_ARGS, char *name);
void __saveds HandleGuiProcObject(METHOD_ARGS);
void __saveds DisGuiProcObject(METHOD_ARGS);
METHOD_TAG guiProcMethods[] =
{
{
METH_PROC_ASSOCIATE,
NULL, NULL,
INVOKE_FORCE_SYNC,
METH_FLAG_OBJECT_AS_DEST, 0,
(METHODFUNCTYPE)AssociateGuiProcObject,
REF_AssociateGuiProcObject
},
{
METH_PROC_HANDLER,
NULL, NULL,
INVOKE_FORCE_SYNC,
METH_FLAG_OBJECT_AS_DEST, 0,
(METHODFUNCTYPE)HandleGuiProcObject, NULL
},
{
METH_PROC_DISASSOCIATE,
NULL, NULL,
INVOKE_FORCE_SYNC,
METH_FLAG_OBJECT_AS_DEST, 0,
(METHODFUNCTYPE)DisGuiProcObject, NULL
},
TAG_END
};
void __saveds *InitAslProcObject(METHOD_ARGS, char *name,
OBJECT junk,
struct SignalSemaphore *semJunk,
struct TagItem *tags);
extern ARGUMENT_TAG REF_InitAslProcObject[];
METHOD_TAG aslProcMethods[] =
{
{
METH_INIT,
NULL, NULL,
INVOKE_CALL,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)InitAslProcObject,
REF_InitAslProcObject
},
TAG_END
};
/*
* ==========================================================================
* = =
* = Class definition for GUI type of objects. =
* = =
* ==========================================================================
*/
ATTRIBUTE_TAG guiAttrs[] =
{
ATTR_GUICHILDREN, FLAG_ATTR_WATCHED | SHADOW_TREE,
NULL,
ATTR_GUISTRUCT, sizeof(struct GUIStruct), NULL,
ATTR_GUIOUTPUT, sizeof(struct OutputStruct), NULL,
TAG_END
};
METHOD_TAG guiMethods[] =
{
{
METH_REMOVE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)GuiRemoveMethod, NULL
},
{
METH_DESTROY,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)GuiDestroyMethod, NULL
},
{
METH_INIT,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
GuiInitMethod, REF_GuiInitMethod
},
{
METH_GUI_STATE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)GuiStateNotify,
REF_GuiStateNotify
},
{
METH_GUI_FOCUS,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)GuiGrabFocus, REF_GuiGrabFocus
},
TAG_END
};
/*
* ==========================================================================
* = =
* = Class definition for window objects. =
* = =
* ==========================================================================
*/
ATTRIBUTE_TAG winAttrs[] =
{
ATTR_WINDOW, sizeof(struct WindowObject), NULL,
TAG_END
};
ARGUMENT_TAG REF_MoveWin[],
REF_PreTitleWindow[];
void MoveWin(METHOD_ARGS, long *);
void WinUpdateMethod(METHOD_ARGS);
BOOL PreTitleWindow(METHOD_ARGS, char *string);
METHOD_TAG winMethods[] =
{
{
METH_INIT,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
WinOpenMethod, REF_WinOpenMethod
},
{
METH_DESTROY,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)WinDestroyMethod, NULL
},
{
METH_WINDOW_CLOSE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)WinCloseMethod, NULL
},
{
METH_WINDOW_PRETITLE,
NULL, NULL,
INVOKE_ASYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)PreTitleWindow,
REF_PreTitleWindow
},
{
METH_WINDOW_UPDATE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)WinUpdateMethod, NULL
},
{
METH_WINDOW_MOVE,
NULL, NULL,
INVOKE_CALL,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)MoveWin,
REF_MoveWin
},
TAG_END
};
/*
* ==========================================================================
* = =
* = Class definition for gadget objects. =
* = =
* ==========================================================================
*/
ATTRIBUTE_TAG gadAttrs[] =
{
ATTR_GADGET, sizeof(struct GadgetObject), NULL,
TAG_END
};
METHOD_TAG gadMethods[] =
{
{
METH_INIT,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
GadgTOpenMethod, REF_GadgTOpenMethod
},
{
METH_GADGET_CHANGE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)GadgTChangeMethod,
REF_GadgTChangeMethod
},
TAG_END
};
/*
* ==========================================================================
* = =
* = Class definition for asl objects. =
* = =
* ==========================================================================
*/
ATTRIBUTE_TAG aslAttrs[] =
{
ATTR_ASLREQUEST, sizeof(struct AslRequest), NULL,
TAG_END
};
extern ARGUMENT_TAG REF_AslOpenMethod[],
REF_AslBeginMethod[],
REF_AslDoneMethod[];
void *AslOpenMethod(METHOD_ARGS, OBJECT window,
char *name,
OBJECT out_object,
char *out_method,
long aslType,
struct TagItem *tags);
extern void AslBeginMethod(METHOD_ARGS, struct TagItem *);
extern void AslLaunchMethod(METHOD_ARGS, struct TagItem *);
extern void AslDoneMethod(METHOD_ARGS, long);
extern void AslRemoveMethod(METHOD_ARGS);
extern void AslDestroyMethod(METHOD_ARGS);
METHOD_TAG aslMethods[] =
{
{
METH_INIT,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
AslOpenMethod, REF_AslOpenMethod
},
{
METH_REMOVE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)AslRemoveMethod, NULL
},
{
METH_DESTROY,
NULL, NULL,
INVOKE_CALL,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)AslDestroyMethod, NULL
},
#define SET_ASL_LAUNCH 3
{
METH_ASL_LAUNCH,
NULL, NULL,
INVOKE_FORCE_ASYNC,
METH_FLAG_CLASS, 0,
(METHODFUNCTYPE)AslLaunchMethod,
REF_AslBeginMethod
},
{
METH_ASL_BEGIN,
NULL, NULL,
INVOKE_CALL,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)AslBeginMethod,
REF_AslBeginMethod
},
{
METH_ASL_DONE,
NULL, NULL,
INVOKE_SYNC,
METH_FLAG_OBJECT, 0,
(METHODFUNCTYPE)AslDoneMethod,
REF_AslDoneMethod
},
TAG_END
};
/*
* ==========================================================================
* = =
* = Initialize these classes =
* = =
* ==========================================================================
*/
void geta4(void);
BOOL InitGUISystem(void)
{
OBJECT guiTask;
CLASS aslProcClass;
BOOL success;
SetupMethodTags(guiProcMethods, (void *)-1, (void *)-1);
SetupMethodTags(aslProcMethods, (void *)-1, (void *)-1);
/*
* Create the guiProcess CLass.
*/
success = AddAutoResource(NULL,CreateSubClass(NULL,
PROCESS_CLASS,
META_CLASS,
GuiProcClassName,
NULL,
guiProcAttrs,
guiProcMethods,
METHOD_END),
GuiProcClassName);
/*
* Create the aslProcess CLass.
*/
success &= AddAutoResource(NULL,
aslProcClass = (CLASS)
UseObject(
CreateSubClass(NULL,
GuiProcClassName,
META_CLASS,
AslProcClassName,
NULL,
NULL,
aslProcMethods,
METHOD_END)),
AslProcClassName);
/*
* Create the guiTask
*/
{
struct TagItem tag[4];
tag[0].ti_Tag = NP_Priority;
tag[0].ti_Data = 1;
tag[1].ti_Tag = NP_StackSize;
tag[1].ti_Data = 6000;
tag[2].ti_Tag = NP_Output;
tag[2].ti_Data = (ULONG)Open("CONSOLE:", MODE_OLDFILE);
tag[3].ti_Tag = TAG_END;
guiTask = CreateInstance(NULL,
GuiProcClassName,
META_CLASS,
GuiTaskName,
FindTask(NULL)->tc_UserData,
NULL,
tag,
METHOD_END);
if (tag[2].ti_Tag != TAG_IGNORE)
Close(tag[2].ti_Data);
}
SetupMethodTags(guiMethods, guiTask, (void *)-1);
SetupMethodTags(winMethods, guiTask, (void *)-1);
SetupMethodTags(gadMethods, guiTask, (void *)-1);
SetupMethodTags(aslMethods, guiTask, (void *)-1);
aslMethods[SET_ASL_LAUNCH].mtag_procObject = aslProcClass;
success &= AddAutoResource(NULL,
CreateSubClass(NULL,
ROOT_CLASS,
META_CLASS,
GuiClassName,
NULL,
guiAttrs,
guiMethods,
METHOD_END),
GuiClassName);
success &= AddAutoResource(NULL,
CreateSubClass(NULL,
GuiClassName,
META_CLASS,
WindowClassName,
NULL,
winAttrs,
winMethods,
METHOD_END),
WindowClassName);
success &= AddAutoResource(NULL,
CreateSubClass(NULL,
GuiClassName,
META_CLASS,
GadgTClassName,
NULL,
gadAttrs,
gadMethods,
METHOD_END),
GadgTClassName);
success &= AddAutoResource(NULL,
CreateSubClass(NULL,
GuiClassName,
META_CLASS,
AslClassName,
NULL,
aslAttrs,
aslMethods,
METHOD_END),
AslClassName);
success &= AddAutoResource(NULL, guiTask, GuiTaskName);
DropObject(aslProcClass);
return success;
}
/*
==========================================================================
gui task
==========================================================================
*/
/*
* First, define the GUI Process Class
*/
void __saveds *AssociateGuiProcObject(METHOD_ARGS, char *name)
{
struct GuiProcess *gui = FindAttribute(object, ATTR_GUIPROCESS);
if (IntuitionBase = OpenLibrary("intuition.library", 36))
{
if (GadToolsBase = OpenLibrary("gadtools.library", 36))
{
if (UtilityBase = OpenLibrary("utility.library", 36))
{
if (AslBase = OpenLibrary("asl.library", 36))
{
if (gui->guip_port = CreateMsgPort())
{
if (DiskfontBase = OpenLibrary("diskfont.library", 0))
{
if (GfxBase = OpenLibrary("graphics.library", 0))
{
if (tf = OpenDiskFont(&ta))
{
if (CallSuper())
return object;
CloseFont(tf);
}
CloseLibrary(GfxBase);
}
CloseLibrary(DiskfontBase);
}
DeleteMsgPort(gui->guip_port);
}
CloseLibrary(AslBase);
}
CloseLibrary(UtilityBase);
}
CloseLibrary(GadToolsBase);
}
CloseLibrary(IntuitionBase);
}
return NULL;
}
void __saveds HandleGuiProcObject(METHOD_ARGS)
{
struct ShadowProcess *sp = FindAttribute(object, ATTR_SHADOWPROCESS);
struct GuiProcess *gui = FindAttribute(object, ATTR_GUIPROCESS);
struct IPCMessage *msg2;
struct IntuiMessage *intui;
ULONG signals;
while(TRUE)
{
signals = Wait( SigBitIPCPort(sp->sp_port) |
SigBitIPCPort(sp->sp_replyPort) |
(1L << gui->guip_port->mp_SigBit) |
SIGBREAKF_CTRL_C);
while(msg2 = GetIPCMessage(sp->sp_port))
ParseShadowMessage(msg2, SHADOW_RETURN_MSG_NEVER);
while(msg2 = GetIPCMessage(sp->sp_replyPort))
JunkIPCMessage(msg2);
while(intui = GT_GetIMsg(gui->guip_port))
HandleIntuiMessage(intui);
if (signals & SIGBREAKF_CTRL_C)
if (sp->sp_flags & SHADOW_PROC_FLAGS_DESTROYED)
break;
}
}
void __saveds DisGuiProcObject(METHOD_ARGS)
{
struct GuiProcess *gui = FindAttribute(object, ATTR_GUIPROCESS);
CloseFont(tf);
CloseLibrary(DiskfontBase);
CloseLibrary(GfxBase);
DeleteMsgPort(gui->guip_port);
CloseLibrary(AslBase);
CloseLibrary(UtilityBase);
CloseLibrary(GadToolsBase);
CloseLibrary(IntuitionBase);
CallSuper();
}
ARGUMENT_TAG REF_InitAslProcObject[] = {
'JSTR', 4, 0,
'JOBJ', 4, 0,
'SEMF', 4, 0,
'TAGL', 4, sizeof(struct TagItem),
TAG_END, SHADOW_RETURN_OBJECT
};
void __saveds *InitAslProcObject(METHOD_ARGS, char *name,
OBJECT junk,
struct SignalSemaphore *semJunk,
struct TagItem *tags)
{
struct TagItem lTags[4];
lTags[0].ti_Tag = NP_Priority;
lTags[0].ti_Data = 0;
lTags[1].ti_Tag = NP_StackSize;
lTags[1].ti_Data = 6000;
lTags[2].ti_Tag = NP_Output;
lTags[2].ti_Data = (ULONG)Open("CONSOLE:", MODE_OLDFILE);
lTags[3].ti_Tag = TAG_MORE;
lTags[3].ti_Data = (ULONG)tags;
ResetPtr(tags, lTags);
if (!CallSuper())
{
Close(lTags[2].ti_Data);
return NULL;
}
return object;
}
/*
*
* GUI CLASS METHODS
*
*/
ARGUMENT_TAG REF_GuiInitMethod[] = {
{'JOBJ', sizeof(void *), SHADOW_OBJECT},
{'JSTR', sizeof(char *), 0},
{'JOBJ', sizeof(void *), SHADOW_OBJECT},
{'JSTR', sizeof(char *), 0},
{TAG_END, SHADOW_RETURN_OBJECT, 0}
};
void *GuiInitMethod(METHOD_ARGS, OBJECT parent,
char *name,
OBJECT out_object,
char *out_method)
{
W_AVLTREE Wtree;
struct GUIStruct *gui;
struct OutputStruct *io;
gui = FindAttribute(object, ATTR_GUISTRUCT);
gui->gui_parent = parent;
if (parent)
Wtree = FindAttribute(parent, ATTR_GUICHILDREN);
io = FindAttribute(object, ATTR_GUIOUTPUT);
io->out_object = out_object;
UseObject(object);
UseObject(parent);
UseObject(out_object);
if (!name || (name = UseString(name)))
{
gui->gui_moniker = name;
if (!out_method || (out_method = UseString(out_method)))
{
io->out_method = out_method;
if (!parent || AddWatchedTreeStringNode(Wtree, object, name))
{
if(DoSuperShadow(object, class, MethodID, METHOD_END))
{
DropObject(object);
return object;
}
if (parent) RemoveWatchedTreeStringNode(Wtree, object, name);
}
DropString(out_method);
}
DropString(name);
}
DropObject(object);
return NULL;
}
/*
* Watch the semaphores!
*/
void GuiRemoveMethod(METHOD_ARGS)
{
struct GUIStruct *gui;
struct OutputStruct *io;
W_AVLTREE children;
OBJECT parent;
DropObject(ReplaceObject(&__GlobalFocus, NULL, object));
gui = FindAttribute(object, ATTR_GUISTRUCT);
io = FindAttribute(object, ATTR_GUIOUTPUT);
PSem(object, SSEM_LOCK);
DropObject(io->out_object);
QuickDropString(io->out_method);
parent = gui->gui_parent;
gui->gui_parent = io->out_object = NULL;
io->out_method = NULL;
VSem(object);
children = FindAttribute(object, ATTR_GUICHILDREN);
PSem(&children->wv_value, SSEM_READ);
while(children->wv_value)
{
OBJECT gadgetObject;
gadgetObject = UseObject((void *)children->wv_value->bn_value);
VSem(&children->wv_value);
DoShadow(gadgetObject, NULL, METH_REMOVE, METHOD_END);
DropObject(gadgetObject);
PSem(&children->wv_value, SSEM_READ);
}
VSem(&children->wv_value);
/*
* remove object from parent list.
*/
if (parent)
{
/*
* Ignore misnomer, please.
* Actually, fellow sblings.
*/
children = FindAttribute(parent, ATTR_GUICHILDREN);
RemoveWatchedTreeStringNode(children, object, gui->gui_moniker);
}
CallSuper();
DropObject(parent);
}
void GuiDestroyMethod(METHOD_ARGS)
{
struct GUIStruct *gui;
gui = FindAttribute(object, ATTR_GUISTRUCT);
QuickDropString(gui->gui_moniker);
CallSuper();
}
ARGUMENT_TAG REF_GuiGrabFocus[] = {'flag', 4, 0, TAG_END};
void GuiGrabFocus(METHOD_ARGS, long flag)
{
DropObject(SetObject(&__GlobalFocus, (flag)?UseObject(object):NULL));
}
/*
* ARGUMENT_TAG for external use!
*/
ARGUMENT_TAG REF_GuiStateNotify[] = {'INTU', 4, sizeof(struct GuiIntuiMsg),
'JOBJ', 4, SHADOW_OBJECT,
TAG_END};
void GuiStateNotify(METHOD_ARGS, struct GuiIntuiMsg *info, OBJECT window)
{
struct OutputStruct *out;
OBJECT obj2;
/*
* Change the focus as required.
*/
if (info)
switch(info->gii_Class)
{
case MOUSEBUTTONS:
if (info->gii_Code & IECODE_UP_PREFIX)
DropObject(ReplaceObject(&__GlobalFocus, NULL, object));
else
DoShadow(object, NULL, METH_GUI_FOCUS,
(void *)TRUE,
METHOD_END);
break;
case INACTIVEWINDOW:
DropObject(ReplaceObject(&__GlobalFocus, NULL, object));
break;
}
out = FindAttribute(object, ATTR_GUIOUTPUT);
if (!(obj2 = GetObject(&out->out_object)))
return;
DoShadow(obj2, NULL, out->out_method, info, window, object, METHOD_END);
DropObject(obj2);
}
/*
*
* WINDOW CLASS METHODS
*
*/
BOOL CalculateWindowPosition(struct WindowLocation *wloc,
struct TagItem *tag,
char *name)
{
struct WindowLocation wl;
struct Screen *screen;
struct Window *win;
ULONG ibaseLock, recurse, origRecurse;
USHORT left, top, height, width;
if (!wloc)
{
return TRUE;
}
if (!(screen = LockPubScreen((char *)GetTagData(WA_PubScreenName,
NULL,
tag))))
{
return FALSE;
}
wl = *wloc;
/*
* Setup the tag's ti_Tag values.
*/
tag[0].ti_Tag = WA_Left;
tag[1].ti_Tag = WA_Top;
tag[2].ti_Tag = (wl.wl_width & WLO_Border)?WA_InnerWidth:WA_Width;
tag[3].ti_Tag = (wl.wl_height & WLO_Border)?WA_InnerHeight:WA_Height;
/*
* Take care of screen-percent stuff. Neat huh?
*/
if (wl.wl_left & WLO_Percent)
{
wl.wl_left &= 0xffff0000;
wl.wl_left |= (screen->Width * (wl.wl_left & 0xffff))/0xffff;
}
if (wl.wl_width & WLO_Percent)
wl.wl_width = (screen->Width * (wl.wl_width & 0xffff))/0xffff;
if (wl.wl_left & WLO_UnderMouse)
wl.wl_left = screen->MouseX;
/*
* Left-Width border check.
*/
if ((wl.wl_left & 0xffff) + (wl.wl_width & 0xffff) > screen->Width)
{
wl.wl_left = max(0, screen->Width - (wl.wl_width & 0xffff));
}
/*
* Top edge screen-percents.
*/
if (wl.wl_top & WLO_Percent)
{
wl.wl_top &= 0xffff0000;
wl.wl_top |= (screen->Height * (wl.wl_top & 0xffff))/0xffff;
}
if (wl.wl_height & WLO_Percent)
wl.wl_height = (screen->Height * (wl.wl_height & 0xffff))/0xffff;
if (wl.wl_top & WLO_UnderMouse)
wl.wl_top = screen->MouseY;
/*
* Top-Height border check.
*/
if ((wl.wl_top & 0xffff) + (wl.wl_height & 0xffff) > screen->Height)
{
wl.wl_top = max(0, screen->Height - (wl.wl_height & 0xffff));
}
/*
* So, now we have the starting positions.
* We need to search the screen for a better, optimal location.
*/
ibaseLock = LockIBase(0L);
height = width = 0;
left = (wl.wl_left &= 0xffff);
top = (wl.wl_top &= 0xffff);
wl.wl_width &= 0xffff;
wl.wl_height &= 0xffff;
name = UseString(name);
/*
* Any other windows of the same name around here?
* We will use their height to pre-calculate the width/height.
*/
for(win = screen->FirstWindow; win; win= win->NextWindow)
{
if (win->Title == name || win->ScreenTitle == name)
{
height = win->Height;
width = win->Width;
if (!wl.wl_width)
{
wl.wl_width = width;
tag[2].ti_Tag = WA_Width;
}
if (!wl.wl_height)
{
wl.wl_height = height;
tag[3].ti_Tag = WA_Height;
}
break;
}
}
if (!(wloc->wl_flags & WLO_NoAuto))
{
recurse = origRecurse = 0;
for(win = screen->FirstWindow; win; win = (win)?win->NextWindow:
screen->FirstWindow)
{
ULONG xInc, yInc, xInc2, yInc2;
/*
* First, is the increment as a percentage of the window
* size, or as straight pixels. The window size is then
* either the win->[Width|Height] -OR- without the borders,
* depending on whether the BORDER bit is set. This way you
* can skip the border PLUS a remaining portion of the window.
*/
if (wl.wl_xInc & WLO_Percent)
{
if (wl.wl_xInc & WLO_Border)
xInc = (((win->Width - win->BorderLeft) *
(wl.wl_xInc & 0xffff))/0xffff);
else
xInc = ((win->Width * (wl.wl_xInc & 0xffff))/0xffff);
} else
xInc = (wl.wl_xInc & 0xffff);
if (wl.wl_yInc & WLO_Percent)
{
if (wl.wl_yInc & WLO_Border)
yInc = (((win->Height - win->BorderTop) *
(wl.wl_yInc & 0xffff))/0xffff);
else
yInc = ((win->Height * (wl.wl_yInc & 0xffff))/0xffff);
} else
yInc = (wl.wl_yInc & 0xffff);
/*
* This is the increment for RE_TILE, as well as a check
* to verify that the window doesn't encroach on another window
* from the left. The above checks if the window itself is
* encroached from the left.
*
* The border size is the same for all windows, so....
*/
if (wl.wl_xInc & WLO_Percent)
{
if (wl.wl_xInc & WLO_Border)
xInc2 = (((width - win->BorderLeft) *
(wl.wl_xInc & 0xffff))/0xffff);
else
xInc2 = ((width * (wl.wl_xInc & 0xffff))/0xffff);
} else
xInc2 = (wl.wl_xInc & 0xffff);
if (wl.wl_yInc & WLO_Percent)
{
if (wl.wl_yInc & WLO_Border)
yInc2 = (((height - win->BorderTop) *
(wl.wl_yInc & 0xffff))/0xffff);
else
yInc2 = ((height * (wl.wl_yInc & 0xffff))/0xffff);
} else
yInc2 = (wl.wl_yInc & 0xffff);
/*
* Add in the border offsets.
*/
if (wl.wl_xInc & WLO_Border)
xInc += win->BorderLeft;
if (wl.wl_yInc & WLO_Border)
yInc += win->BorderTop;
if (wl.wl_xInc & WLO_Border)
xInc2 += win->BorderLeft;
if (wl.wl_yInc & WLO_Border)
yInc2 += win->BorderTop;
/*
* Is window either:
* a) encroached on by another window or
* b) encraching ON another window.
*
* b) calculation won't work for the first parameter window
* of a module....
*/
if ((left - win->LeftEdge < ((xInc)?xInc:1) &&
left - win->LeftEdge >= 0 &&
top - win->TopEdge < ((yInc)?yInc:1) &&
top - win->TopEdge >= 0) ||
(win->LeftEdge - left < ((xInc2)?xInc2:1) &&
win->LeftEdge - left >= 0 &&
win->TopEdge - top < ((yInc2)?yInc2:1) &&
win->TopEdge - top >= 0))
{
BOOL changed = FALSE;
if (recurse)
{
--recurse;
continue;
}
if (!( ( (wl.wl_flags & WLO_TileHoriz) &&
(wl.wl_flags & WLO_ReTile) ) ||
( (wl.wl_flags & WLO_TileVert) &&
!(wl.wl_flags & WLO_TileHoriz) &&
!(wl.wl_flags & WLO_ReTile) )) &&
!(wloc->wl_left & WLO_UnderMouse))
{
if (wl.wl_flags & WLO_ReTile)
left += ((xInc2)?xInc2:xInc);
else
left = win->LeftEdge + xInc;
changed = TRUE;
}
if (!( ( (wl.wl_flags & WLO_TileVert ) &&
(wl.wl_flags & WLO_ReTile) ) ||
( (wl.wl_flags & WLO_TileHoriz) &&
!(wl.wl_flags & WLO_TileVert ) &&
!(wl.wl_flags & WLO_ReTile) )) &&
!(wloc->wl_top & WLO_UnderMouse))
{
if (wl.wl_flags & WLO_ReTile)
top += ((yInc2)?yInc2:yInc);
else
top = win->TopEdge + yInc;
changed = TRUE;
}
if (!changed && !(wl.wl_flags & WLO_ReTile))
/*
* Caught in non-update loop!
*/
break;
wl.wl_flags &= ~WLO_ReTile;
/*
* Double border problem?
*/
if ((top + ((height)?height:win->Height) > screen->Height) &&
(left + ((width)?width:win->Width) > screen->Width))
{
top = wl.wl_top;
left = wl.wl_left & 0xffff;
if (top == wl.wl_top |
left == wl.wl_left)
break;
origRecurse++;
wl.wl_flags &= ~(WLO_ResetHoriz | WLO_ResetVert);
}
/*
* Border collision check.
*/
if (top + ((height)?height:win->Height) > screen->Height)
{
if (top == wl.wl_top)
break;
top = wl.wl_top;
wl.wl_flags |= WLO_ResetVert;
if (wl.wl_flags & WLO_TileVert)
wl.wl_flags |= WLO_ReTile;
if (wl.wl_flags & WLO_ResetHoriz ||
!wl.wl_xInc ||
(wloc->wl_left & WLO_UnderMouse))
{
origRecurse++;
wl.wl_flags &= ~(WLO_ResetHoriz | WLO_ResetVert);
}
}
if (left + ((width)?width:win->Width) > screen->Width)
{
if (left == wl.wl_left)
break;
left = wl.wl_left;
wl.wl_flags |= WLO_ResetHoriz;
if (wl.wl_flags & WLO_TileHoriz)
wl.wl_flags |= WLO_ReTile;
if (wl.wl_flags & WLO_ResetVert ||
!wl.wl_yInc ||
(wloc->wl_top & WLO_UnderMouse))
{
origRecurse++;
wl.wl_flags &= ~(WLO_ResetHoriz | WLO_ResetVert);
}
}
recurse = origRecurse;
win = NULL;
}
}
}
tag[0].ti_Data = left;
tag[1].ti_Data = top;
tag[2].ti_Data = (wl.wl_width)?wl.wl_width:1;
tag[3].ti_Data = (wl.wl_height)?wl.wl_height:1;
UnlockIBase(ibaseLock);
QuickDropString(name);
UnlockPubScreen(NULL, screen);
return TRUE;
}
/*
* METH_INIT
*/
ARGUMENT_TAG REF_WinOpenMethod[] = {
{'JOBJ', sizeof(void *), SHADOW_OBJECT},
{'JSTR', sizeof(char *), 0},
{'JOBJ', sizeof(void *), SHADOW_OBJECT},
{'JSTR', sizeof(char *), 0},
{'TAGL', sizeof(void *),
sizeof(struct TagItem)},
{'JOBJ', sizeof(OBJECT), SHADOW_OBJECT},
{TAG_END, SHADOW_RETURN_OBJECT, 0}
};
void *WinOpenMethod(METHOD_ARGS, OBJECT parent,
char *name,
OBJECT out_object,
char *out_method,
struct TagItem *tags,
OBJECT wlObject)
{
struct WindowObject *wobj;
struct WindowLocation *wl;
struct TagItem tag[5];
tag[0].ti_Tag = tag[4].ti_Tag = TAG_MORE;
tag[0].ti_Data = tag[4].ti_Data = (ULONG)tags;
if (!CalculateWindowPosition(wl = (void *)GetTagData(WLO_Location,
NULL,
tags),
tag,
name))
{
DropObject(UseObject(object));
return NULL;
}
UseObject(object);
wobj = FindAttribute(object, ATTR_WINDOW);
name = UseString(name);
if (wobj->wo_window = OpenWindowTags(NULL, WA_Flags, 0xf,
WA_Title, name,
TAG_MORE, tag))
{
struct GuiProcess *gui;
gui = FindAttribute(FindTask(NULL)->tc_UserData, ATTR_GUIPROCESS);
wobj->wo_window->UserPort = gui->guip_port;
wobj->wo_window->UserData = (void *)object;
/*
* Would require V37 to check ModifyIDCMP!
*/
ModifyIDCMP(wobj->wo_window, LISTVIEWIDCMP | CLOSEWINDOW |
REFRESHWINDOW | INACTIVEWINDOW |
ACTIVEWINDOW);
{
if (wobj->wo_vi = GetVisualInfo(wobj->wo_window->WScreen, TAG_END))
{
if (wobj->wo_lastGadget = CreateContext(&wobj->wo_rootGadget))
{
AddGList(wobj->wo_window, wobj->wo_rootGadget, -1, -1, NULL);
/*
* Force tags to NULL -- ick, I hate optimizers.
*/
ForceMethodEnd(out_method);
if (CallSuper())
{
/*
* Used twice, once for return, once in window structure.
*/
/*
* Name is in superClass under gui->gui_moniker
*/
DropString(name);
wobj->wo_wl = wl;
if (wl && (wl->wl_flags & WLO_Backstore) && wlObject)
{
wl->wl_localLeft = wobj->wo_window->LeftEdge;
wl->wl_localTop = wobj->wo_window->TopEdge;
wl->wl_localWidth = wobj->wo_window->Width;;
wl->wl_localHeight = wobj->wo_window->Height;
}
DropObject(SetObject(&wobj->wo_wlObject,
UseObject(wlObject)));
return object;
}
}
}
}
DropString(name);
DoShadow(object, NULL, METH_WINDOW_CLOSE, METHOD_END);
return NULL;
}
DropString(name);
DropObject(object);
return NULL;
}
void WinDestroyMethod(METHOD_ARGS)
{
struct WindowObject *wobj = FindAttribute(object, ATTR_WINDOW);
char *localWindowName = wobj->wo_localWindowName;
struct Window *window;
if (window = wobj->wo_window)
{
if (wobj->wo_rootGadget)
{
FreeGadgets(wobj->wo_rootGadget);
}
CloseWindow(window);
}
FreeVisualInfo(wobj->wo_vi);
CallSuper();
if (localWindowName)
FreeMem(localWindowName, strlen(localWindowName) + 1);
}
void WinUpdateMethod(METHOD_ARGS)
{
struct WindowObject *wo;
struct WindowLocation *wl;
OBJECT wlObject;
wo = FindAttribute(object, ATTR_WINDOW);
/*
* Figure out what to do with the location stuff, if anything.
*/
/*
* Reset leftedge/topedge if -modified- from original setting set
* NOAUTO!
*/
if ((wlObject = GetObject(&wo->wo_wlObject)) &&
(wl = wo->wo_wl) &&
(wl->wl_flags & WLO_Backstore))
{
if (wo->wo_window->LeftEdge != wl->wl_localLeft ||
wo->wo_window->TopEdge != wl->wl_localTop ||
wo->wo_window->Width != wl->wl_localWidth ||
wo->wo_window->Height != wl->wl_localHeight)
{
wl->wl_left = wo->wo_window->LeftEdge;
wl->wl_width = wo->wo_window->Width;
wl->wl_top = wo->wo_window->TopEdge;
wl->wl_height = wo->wo_window->Height;
wl->wl_flags |= WLO_NoAuto;
}
}
DropObject(wlObject);
}
void WinCloseMethod(METHOD_ARGS)
{
struct WindowObject *wo;
struct Window *window;
wo = FindAttribute(object, ATTR_WINDOW);
/*
* Update window locations.
*/
DoShadow(object, NULL, METH_WINDOW_UPDATE, METHOD_END);
DropObject(SetObject(&wo->wo_wlObject, NULL));
/*
* Should remove all child gadgets.
*/
if (window = wo->wo_window)
{
RemoveGList(window, wo->wo_rootGadget, -1);
RemoveWinSafely(window); /* Unuses object from UserData field */
}
CallSuper();
}
ARGUMENT_TAG REF_MoveWin[] = {'APTR', 4, sizeof(ULONG) * 4, TAG_END};
void MoveWin(METHOD_ARGS, long *pos)
{
struct WindowObject *wo;
if (!pos)
return;
wo = FindAttribute(object, ATTR_WINDOW);
ChangeWindowBox(wo->wo_window, pos[0], pos[1], pos[2], pos[3]);
}
ARGUMENT_TAG REF_PreTitleWindow[] = {'JSTR', 4, 0, TAG_END};
/*
* ASYNC, so the return is ignored, but just in case....
*/
BOOL PreTitleWindow(METHOD_ARGS, char *string)
{
struct GUIStruct *gui = FindAttribute(object, ATTR_GUISTRUCT);
struct WindowObject *wo = FindAttribute(object, ATTR_WINDOW);
char *title;
int length;
if ( (length = strlen(string) + strlen(gui->gui_moniker)) > 250)
{
return FALSE;
}
PSem(&wo->wo_localWindowName, SSEM_WRITE);
if (wo->wo_localWindowName)
FreeMem(wo->wo_localWindowName, strlen(wo->wo_localWindowName) + 1);
if (title = wo->wo_localWindowName = AllocMem(length + 4, MEMF_PUBLIC))
{
strcpy(title, string);
strcat(title, " : ");
strcat(title, gui->gui_moniker);
SetWindowTitles(wo->wo_window, title, (char *)-1);
VSem(&wo->wo_localWindowName);
return TRUE;
}
VSem(&wo->wo_localWindowName);
return FALSE;
}
/*
*
* GADGT METHODS
*
*/
ARGUMENT_TAG REF_GadgTOpenMethod[] =
{
'JOBJ', sizeof(OBJECT),
SHADOW_OBJECT,
'JSTR', sizeof(char *), 0,
'JOBJ', sizeof(void *),
SHADOW_OBJECT,
'JSTR', sizeof(char *), 0,
'NGAD', sizeof(struct NewGadget *),
sizeof(struct NewGadget),
'type', sizeof(long), 0,
'TAGL', sizeof(void *),
sizeof(struct TagItem),
{TAG_END, SHADOW_RETURN_OBJECT, 0}
};
void *GadgTOpenMethod(METHOD_ARGS, OBJECT window,
char *name,
OBJECT out_object,
char *out_method,
struct NewGadget *ng,
long gadType,
struct TagItem *tags)
{
struct GadgetObject *gobj;
struct WindowObject *windowObj;
UseObject(object);
if (!window || !ng)
{
DropObject(object);
return NULL;
}
gobj = FindAttribute(object, ATTR_GADGET);
if (!(windowObj = FindAttribute(window, ATTR_WINDOW)))
{
DropObject(object);
return NULL;
}
ng->ng_TextAttr = &ta;
ng->ng_VisualInfo = windowObj->wo_vi;
ng->ng_UserData = object;
ng->ng_GadgetText = UseString(name);
ng->ng_GadgetID = gadType;
RemoveGList(windowObj->wo_window, windowObj->wo_rootGadget, -1);
if (gobj->go_gadget = CreateGadgetA(gadType, windowObj->wo_lastGadget, ng, tags))
{
AddGList(windowObj->wo_window, windowObj->wo_rootGadget, -1, -1, NULL);
ForceMethodEnd(ng);
if (CallSuper())
{
RefreshGList(windowObj->wo_lastGadget, windowObj->wo_window, NULL, ((UWORD)-1));
windowObj->wo_lastGadget = gobj->go_gadget;
GT_RefreshWindow(windowObj->wo_window, NULL);
/*
* name used by superClass, can drop it here.
* Otherwise would have to subclass METH_DESTROY, which would suck.
*/
DropString(name);
DropObject(object);
return object;
}
} else
AddGList(windowObj->wo_window, windowObj->wo_rootGadget, -1, -1, NULL);
DropObject(object);
return NULL;
}
ARGUMENT_TAG REF_GadgTChangeMethod[] =
{
'TAGL', sizeof(void *),
sizeof(struct TagItem),
TAG_END
};
void GadgTChangeMethod(METHOD_ARGS, struct TagItem *tags)
{
struct GadgetObject *gobj;
struct GUIStruct *gui;
struct WindowObject *windowObj;
gobj = FindAttribute(object, ATTR_GADGET);
gui = FindAttribute(object, ATTR_GUISTRUCT);
windowObj = FindAttribute(gui->gui_parent, ATTR_WINDOW);
GT_SetGadgetAttrsA(gobj->go_gadget, windowObj->wo_window, NULL, tags);
}
/*
*
* ASL METHODS
*
*/
ARGUMENT_TAG REF_AslOpenMethod[] =
{
'JOBJ', sizeof(OBJECT),
SHADOW_OBJECT,
'JSTR', sizeof(char *), 0,
'JOBJ', sizeof(void *),
SHADOW_OBJECT,
'JSTR', sizeof(char *), 0,
'type', sizeof(long), 0,
'TAGL', sizeof(void *),
sizeof(struct TagItem),
{TAG_END, SHADOW_RETURN_OBJECT, 0}
};
void *AslOpenMethod(METHOD_ARGS, OBJECT window,
char *name,
OBJECT out_object,
char *out_method,
long gadType,
struct TagItem *tags)
{
struct AslRequest *aslR;
struct WindowObject *windowObj;
struct TagItem lTags[10], *t = lTags, *t2;
aslR = FindAttribute(object, ATTR_ASLREQUEST);
aslR->ar_gadType = gadType;
if (!(t2 = FindTagItem(ASL_Window, tags)) &&
(windowObj = FindAttribute(window, ATTR_WINDOW)))
{
t->ti_Tag = ASL_Window,
t->ti_Data = (ULONG)windowObj->wo_window;
t++;
} else if (t2)
{
struct Window *win;
win = (struct Window *)t2->ti_Data;
*(OBJECT *)((ULONG)&window) = (OBJECT)win->UserData;
}
if (!FindTagItem(ASL_Hail, tags))
{
t->ti_Tag = ASL_Hail;
t->ti_Data = (ULONG)UseString(name);
t++;
} else UseString(name);
if (t2 = FindTagItem(ASL_FuncFlags, tags))
{
t2->ti_Data |=
((gadType == ASL_FileRequest)?FILF_NEWIDCMP:FONF_NEWIDCMP);
} else
{
t->ti_Tag = ASL_FuncFlags;
t->ti_Data = (gadType == ASL_FileRequest)?FILF_NEWIDCMP:FONF_NEWIDCMP;
t++;
}
t->ti_Tag = TAG_MORE;
t->ti_Data = (ULONG)tags;
if (aslR->ar_Requester = AllocAslRequest(gadType, lTags))
{
ForceMethodEnd(gadType);
if (CallSuper())
{
/*
* name used by superClass, can drop it here.
* Otherwise would have to subclass METH_DESTROY, which would suck.
*/
DropString(name);
aslR->ar_ParentWindow = UseObject(window);
return object;
}
FreeAslRequest(aslR->ar_Requester);
aslR->ar_Requester = NULL;
}
DropString(name);
DropObject(UseObject(object));
return NULL;
}
ARGUMENT_TAG REF_AslBeginMethod[] = {
'TAGL', sizeof(void *),
sizeof(struct TagItem),
TAG_END
};
void AslBeginMethod(METHOD_ARGS, struct TagItem *tags)
{
struct AslRequest *ar = FindAttribute(object, ATTR_ASLREQUEST);
struct TagItem *t;
if (ar->ar_OpenFlag & (ASL_FLAG_BEGUN | ASL_FLAG_REMOVE))
return;
ar->ar_OpenFlag |= ASL_FLAG_BEGUN;
if (t = FindTagItem(ASL_Window, tags))
{
struct Window *win;
win = (struct Window *)t->ti_Data;
DropObject(SetObject(&ar->ar_LocalWindow,
UseObject((OBJECT)win->UserData)));
DropObject(SetObject(&ar->ar_ParentWindow, NULL));
}
if ((ar->ar_gadType == ASL_FontRequest) &&
(t = FindTagItem(ASL_FontName, tags)))
t->ti_Data = (ULONG)(ar->ar_FontName = UseString((char *)t->ti_Data));
if (ar->ar_gadType == ASL_FileRequest)
{
if (t = FindTagItem(ASL_File, tags))
t->ti_Data = (ULONG)(ar->ar_File = UseString((char *)t->ti_Data));
if (t = FindTagItem(ASL_Dir, tags))
t->ti_Data = (ULONG)(ar->ar_Dir = UseString((char *)t->ti_Data));
}
if (t = FindTagItem(ASL_OKText, tags))
t->ti_Data = (ULONG)(ar->ar_OKText = UseString((char *)t->ti_Data));
if (t = FindTagItem(ASL_CancelText, tags))
t->ti_Data = (ULONG)(ar->ar_CancelText = UseString((char *)t->ti_Data));
DoShadow(object, NULL, METH_ASL_LAUNCH, tags, METHOD_END);
}
void AslLaunchMethod(METHOD_ARGS, struct TagItem *tags)
{
struct AslRequest *ar = FindAttribute(object, ATTR_ASLREQUEST);
DoShadow(object,
NULL,
METH_ASL_DONE,
(void *)AslRequest(ar->ar_FileRequester, tags),
METHOD_END);
}
ARGUMENT_TAG REF_AslDoneMethod[] = {
'long', 4, 0,
TAG_END
};
void AslDoneMethod(METHOD_ARGS, long succeed)
{
OBJECT output;
struct AslRequest *ar;
struct OutputStruct *io;
ar = FindAttribute(object, ATTR_ASLREQUEST);
DropString(ar->ar_FontName);
DropString(ar->ar_File);
DropString(ar->ar_Dir);
DropString(ar->ar_OKText);
DropString(ar->ar_CancelText);
DropObject(SetObject(&ar->ar_LocalWindow, NULL));
ar->ar_FontName = NULL;
ar->ar_File = NULL;
ar->ar_Dir = NULL;
ar->ar_OKText = NULL;
ar->ar_CancelText = NULL;
ar->ar_OpenFlag &= ~ASL_FLAG_BEGUN;
io = FindAttribute(object, ATTR_GUIOUTPUT);
output = GetObject(&io->out_object);
DoShadow(output, NULL, io->out_method, object, succeed, METHOD_END);
DropObject(output);
if (ar->ar_OpenFlag & ASL_FLAG_REMOVE)
{
DropObject(SetObject(&ar->ar_ParentWindow, NULL));
}
}
void AslRemoveMethod(METHOD_ARGS)
{
struct AslRequest *ar;
ar = FindAttribute(object, ATTR_ASLREQUEST);
ar->ar_OpenFlag |= ASL_FLAG_REMOVE;
if (!(ar->ar_OpenFlag & ASL_FLAG_BEGUN))
{
DropObject(SetObject(&ar->ar_LocalWindow, NULL));
DropObject(SetObject(&ar->ar_ParentWindow, NULL));
}
CallSuper();
}
void AslDestroyMethod(METHOD_ARGS)
{
struct AslRequest *ar;
ar = FindAttribute(object, ATTR_ASLREQUEST);
FreeAslRequest(ar->ar_Requester);
ar->ar_Requester = NULL;
CallSuper();
}
/*
==============================================================================
= =
= SUPPLEMENTARY =
= =
==============================================================================
*/
void HandleIntuiMessage(struct IntuiMessage *intui)
{
OBJECT winObject, gadObject;
int class;
if (!intui)
return;
winObject = UseObject((OBJECT)intui->IDCMPWindow->UserData);
switch(class = intui->Class) {
case NEWSIZE:
DoShadow(winObject,
NULL,
METH_GUI_RESIZE,
(void *)intui->IDCMPWindow->LeftEdge,
(long)intui->IDCMPWindow->TopEdge,
(long)intui->IDCMPWindow->Width,
(long)intui->IDCMPWindow->Height,
METHOD_END);
break;
case CLOSEWINDOW:
{
struct IntuiMessage intui2 = *intui;
GT_ReplyIMsg(intui);
DoShadow(winObject,
NULL,
METH_WINDOW_CLOSE,
&intui2.Class,
winObject,
METHOD_END);
break;
}
case NEWPREFS:
case DISKINSERTED:
case DISKREMOVED:
case ACTIVEWINDOW:
case INACTIVEWINDOW:
case CHANGEWINDOW:
DoShadow(winObject,
NULL,
METH_GUI_STATE,
&intui->Class,
winObject,
METHOD_END);
break;
case MOUSEBUTTONS:
case MOUSEMOVE:
case RAWKEY:
case DELTAMOVE:
case VANILLAKEY:
case INTUITICKS:
gadObject = GetObject(&__GlobalFocus);
DoShadow((gadObject)?gadObject:winObject,
NULL,
METH_GUI_STATE,
&intui->Class,
winObject,
METHOD_END);
DropObject(gadObject);
break;
case REFRESHWINDOW:
GT_BeginRefresh(intui->IDCMPWindow);
DoShadow(winObject,
NULL,
METH_WINDOW_REFRESH,
&intui->Class,
winObject,
METHOD_END);
GT_EndRefresh(intui->IDCMPWindow, TRUE);
break;
case GADGETDOWN:
case GADGETUP:
gadObject = GetObject((OBJECT *)&
((struct Gadget *)intui->IAddress)->UserData);
DoShadow(gadObject, NULL, METH_GUI_STATE,
&intui->Class,
winObject,
METHOD_END);
DropObject(gadObject);
break;
default:
break;
}
if (class != CLOSEWINDOW)
GT_ReplyIMsg(intui);
DropObject(winObject);
}
void RemoveWinSafely(struct Window *win)
{
void *object;
object = win->UserData;
if (win->UserPort)
{
Forbid();
StripIntuiMessages(win->UserPort, win);
win->UserPort = NULL;
ModifyIDCMP(win, NULL);
win->UserData = NULL;
Permit();
/*
* stop using this object in window structure.
*/
DropObject(object);
}
}
void StripIntuiMessages(struct MsgPort *port, struct Window *win)
{
struct IntuiMessage *msg;
struct Node *succ;
msg = (struct IntuiMessage *)port->mp_MsgList.lh_Head;
while(succ = msg->ExecMessage.mn_Node.ln_Succ)
{
if (msg->IDCMPWindow == win)
{
Remove(msg);
ReplyMsg(msg);
}
msg = (struct IntuiMessage *)succ;
}
}